/*
 * Copyright 2008 Neil Bacon
 * Distributed under the terms of the Mozilla Public License version 1.1
 * or the GNU General Public License version 3.
 */

package nb.xadd.operator;

import java.util.BitSet;

import nb.util.IntMap;
import nb.xadd.operator.impl.PieceWiseConstantApproximation.Type;


public interface OperatorFactory {

    BinaryOperator getAddition();

    BinaryOperator getMultiplication();

    /**
     * Maximum - only ConstantValueNodes are handled, other types of terminal nodes
     * will throw MDPNotYetImplemented.
     */
    BinaryOperator getBinaryMaximum();

    /**
     * Maximum - only ConstantValueNodes are handled, other types of terminal nodes
     * will throw MDPNotYetImplemented.
     * @param booleanVarIndexSet
     * @param realVarIndexSet
     * @return operator
     */
    UnaryOperator getUnaryMaximum(BitSet booleanVarIndexSet, BitSet realVarIndexSet);
    
    /**
     * Negate tests on the specified variables (swap true and false children).
     * @param booleanVarIndexSet
     * @param realVarIndexSet
     * @return operator
     */
    UnaryOperator getNegation(BitSet booleanVarIndexSet, BitSet realVarIndexSet);
    
    /**
     * Variable substitution.
     * @param booleanVarMap current Boolean variable index -> new Boolean variable index
     * @param realVarMap current real variable index -> new real variable index
     * @return operator
     */
    UnaryOperator getVariableSubstitution(IntMap booleanVarMap, IntMap realVarMap);

    /**
     * Integration over the variables specified by realVarIndexSet.
     * RealGreaterOrEqualDecisionNodes on the integration variables are eliminated.
     * All terminal nodes must be ConstantValueNodes,
     * the implementation is incorrect for other AbstractValueNodes.
     * @param booleanVarIndexSet boolean integration variables
     * @param realVarIndexSet real integration variables
     * @return operator
     */
    UnaryOperator getIntegration(BitSet booleanVarIndexSet, BitSet realVarIndexSet);

    /**
     * Replace LinearValueNodes with a Piecewise Constant Function.
     * All terminal nodes must be ConstantValueNodes or LinearValueNodes or a MDPRuntimeException is thrown.
     * @param type minimum error or upper or lower bound approximation
     * @param errorLimit maximum difference between the approximation and the actual value
     * @param pieceCountLimit
     * When the slope is too high, achieving the errorLimit requires more pieces than this.
     * In this case the number of pieces is limited to this value, a warning is logged and the errorLimit is violated. 
     * @return operator
     */
    UnaryOperator getPieceWiseConstantApproximation(Type type, double errorLimit, int pieceCountLimit);

    /**
     * Correct the order of decision nodes.
     * @return operator
     */
    UnaryOperator getSort();

}
